﻿using System;
using System.IO;
using LBNet;

public class NetWork
{
    private Connector m_Connector = null;
    private Protocol m_Protocol = null;

    private string m_sIP = "";
    private int m_nPort = 0;

    public string IP
    {
        get { return m_sIP; }
    }

    public int Port
    {
        get { return m_nPort; }
    }

    public bool IsWorking
    {
        get { return (m_Connector != null && m_Connector.IsWorking()); }
    }

    public void StartNetWork(string ip, int port)
    {
        m_sIP = ip;
        m_nPort = port;

        if (m_Protocol == null)
        {
            m_Protocol = new Protocol();
            InitialProtocol();
        }

        if (m_Connector == null)
        {
            m_Connector = new Connector(m_sIP, m_nPort);
            m_Connector.OnConnected += new EventHandler<EventArgs>(OnConnected);
            m_Connector.OnConnectFailed += new EventHandler<EventArgs>(OnConnectFailed);
            m_Connector.OnDisconnected += new EventHandler<EventArgs>(OnDisconnected);
            m_Connector.OnReceived += new EventHandler<NetEventArg_Received>(ReceiveProtocol);
            m_Connector.StartConnect();
        }
    }

    public void StopNetWork()
    {
        if (m_Protocol != null)
        {
            m_Protocol = null;
        }

        if (m_Connector != null)
        {
            m_Connector.OnConnected -= new EventHandler<EventArgs>(OnConnected);
            m_Connector.OnConnectFailed -= new EventHandler<EventArgs>(OnConnectFailed);
            m_Connector.OnDisconnected -= new EventHandler<EventArgs>(OnDisconnected);
            m_Connector.OnReceived -= new EventHandler<NetEventArg_Received>(ReceiveProtocol);

            if (!m_Connector.IsStopped())
                m_Connector.CloseConnect();
            
            m_Connector = null;
        }
    }

    public void Update()
    {
        if (m_Protocol != null)
        {
            m_Protocol.ProcessMsg();
        }

        if (m_Connector != null)
        {
            m_Connector.Update();
        }
    }

    private void SendData(byte[] byData)
    {
        if (m_Connector != null)
        {
            m_Connector.SendToServer(byData);
        }
    }

    public void SendRPC(ushort op)
    {
        byte[] data = new byte[LBNet.NetDefine.HEAD_LEN_SIZE + LBNet.NetDefine.HEAD_OP_SIZE];
        BitConverter.GetBytes(0).CopyTo(data, 0);
        BitConverter.GetBytes(op).CopyTo(data, LBNet.NetDefine.HEAD_LEN_SIZE);
        if (!BitConverter.IsLittleEndian)
        {
            Array.Reverse(data, 0, LBNet.NetDefine.HEAD_LEN_SIZE);
            Array.Reverse(data, LBNet.NetDefine.HEAD_LEN_SIZE, LBNet.NetDefine.HEAD_OP_SIZE);
        }
        SendData(data);
    }

    public void SendRPC<T>(ushort op, T rpc)
    {
        MemoryStream memStream = new MemoryStream();
        

        //ProtoBuf.Serializer.Serialize<T>(memStream, rpc);

        Int32 len = (Int32)memStream.Length;
        byte[] data = new byte[LBNet.NetDefine.HEAD_LEN_SIZE + LBNet.NetDefine.HEAD_OP_SIZE + len];
        BitConverter.GetBytes(len).CopyTo(data, 0);
        BitConverter.GetBytes(op).CopyTo(data, LBNet.NetDefine.HEAD_LEN_SIZE);
        if (!BitConverter.IsLittleEndian)
        {
            Array.Reverse(data, 0, LBNet.NetDefine.HEAD_LEN_SIZE);
            Array.Reverse(data, LBNet.NetDefine.HEAD_LEN_SIZE, LBNet.NetDefine.HEAD_OP_SIZE);
        }

        memStream.ToArray().CopyTo(data, LBNet.NetDefine.HEAD_LEN_SIZE + LBNet.NetDefine.HEAD_OP_SIZE);
        memStream.Close();
        SendData(data);
    }

    protected void RegisterMsg(ushort opCode, string msgType, ProtocolHandler h)
    {
        m_Protocol.RegisterMsg(opCode, msgType, h);
    }

    protected virtual void InitialProtocol()
    {

    }

    protected virtual void OnConnected(object src, EventArgs arg)
    {
        Debugger.Log("链接成功");
    }

    protected virtual void OnConnectFailed(object src, EventArgs arg)
    {
        Debugger.Log("连接失败");
    }

    protected virtual void OnDisconnected(object src, EventArgs arg)
    {
        Debugger.Log("断开链接");
    }

    protected virtual void ReceiveProtocol(object src, NetEventArg_Received arg)
    {
        if (m_Protocol != null)
        {
            m_Protocol.ReceiveProtocol(src, arg);
        }
    }
}